#include "Signal_433.h"
#include "lstimer.h"
#include <string.h>
#include "io_config.h"
#include "platform.h"
#include "board_config.h"
#include <stdio.h>

#define TIM_PRESCALER (SDK_HCLK_MHZ - 1)
void Get_Signal_433(unsigned int dataCount);
struct
{
    unsigned int Recive_Data;
    unsigned int Clear_Count;
} Signal_433_Parameter;

TIM_HandleTypeDef Capture_TimHandle;
typedef struct
{
    uint8_t ucStartFlag;
    uint16_t usCtr;
    uint16_t usPeriod;
} capture_t;
capture_t TIM_ICUserValueStructure = {0};

static uint32_t ch1_cnt;
static TIM_IC_InitTypeDef IC_Config = {0};
static void Input_Capture_Measurement_Cfg(void)
{
    Capture_TimHandle.Instance = LSGPTIMC;
    Capture_TimHandle.Init.Prescaler = TIM_PRESCALER;
    Capture_TimHandle.Init.Period = 0xFFFF;
    Capture_TimHandle.Init.ClockDivision = 0;
    Capture_TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
    Capture_TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    HAL_TIM_Init(&Capture_TimHandle);

    IC_Config.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
    IC_Config.ICSelection = TIM_ICSELECTION_DIRECTTI;
    IC_Config.ICPrescaler = TIM_ICPSC_DIV1;
    IC_Config.ICFilter = 0xf;
    TIM_ICUserValueStructure.ucStartFlag = 1;
    HAL_TIM_IC_ConfigChannel(&Capture_TimHandle, &IC_Config, TIM_CHANNEL_1);
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == LSGPTIMC)
    {
        TIM_ICUserValueStructure.usPeriod++;
    }
}

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{

    if (TIM_ICUserValueStructure.ucStartFlag == 0)
    {
        ch1_cnt = TIM_ICUserValueStructure.usPeriod * 65535 + HAL_TIM_ReadCapturedValue(&Capture_TimHandle, TIM_CHANNEL_1) - TIM_ICUserValueStructure.usCtr;
        Get_Signal_433(ch1_cnt);

        IC_Config.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
        TIM_ICUserValueStructure.ucStartFlag = 1;
        TIM_ICUserValueStructure.usCtr = 0;
    }
    else
    {
        TIM_ICUserValueStructure.usCtr = HAL_TIM_ReadCapturedValue(&Capture_TimHandle, TIM_CHANNEL_1);
        // Configure the input capture parameters, modify the trigger level
        IC_Config.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
        TIM_ICUserValueStructure.usPeriod = 0;
        TIM_ICUserValueStructure.ucStartFlag = 0;
    }
    // Clear interrupt flag bits
    HAL_TIM_IC_ConfigChannel(&Capture_TimHandle, &IC_Config, TIM_CHANNEL_1);
    __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
    // Start input capture and enable interrupts
    HAL_TIM_IC_Start_IT(&Capture_TimHandle, TIM_CHANNEL_1);
}

XIP_BANNED void Get_Signal_433(unsigned int dataCount)
{
    static unsigned char Count;
    static unsigned int Data;

    if (Count == 0)
    {
        if (dataCount > SIGNAL_HEAD_MIN_US && dataCount < SIGNAL_HEAD_MAX_US)
        {
            Count += 1;
        }
    }
    else
    {
        if (dataCount > SIGNAL_NARROW_MIN_US && dataCount < SIGNAL_NARROW_MAX_US)
        {
            io_set_pin(PB12);
            Data += 1;
            Data <<= 1;
            Count += 1;
        }
        else
        {
            if (dataCount > SIGNAL_WIDE_MIN_US && dataCount < SIGNAL_WIDE_MAX_US)
            {
                io_clr_pin(PB12);
                Data <<= 1;
                Count += 1;
            }
            else
            {
                Data = 0;
                Count = 0;
            }
        }

        if (Count >= 24)
        {
            Signal_433_Parameter.Clear_Count = 5;
            Signal_433_Parameter.Recive_Data = Data;
            signal_433_callback(Signal_433_Parameter.Recive_Data);
            Data = 0;
            Count = 0;
        }
    }
}
__attribute__((weak)) void signal_433_callback(uint32_t data)
{

}
void ble_signal_433_init(uint8_t signal_433_pin)
{
    gptimc1_ch1_io_init(signal_433_pin, false, 0);
    io_pull_write(signal_433_pin, IO_PULL_DOWN);
    Input_Capture_Measurement_Cfg();
}

void ble_signal_433_start(void)
{
    HAL_TIM_Base_Start_IT(&Capture_TimHandle);
    HAL_TIM_IC_Start_IT(&Capture_TimHandle, TIM_CHANNEL_1);
}

void ble_signal_433_stop(void)
{
    HAL_TIM_Base_Stop_IT(&Capture_TimHandle);
    HAL_TIM_IC_Stop_IT(&Capture_TimHandle, TIM_CHANNEL_1);
}
